﻿CREATE OR REPLACE FUNCTION "SKLAD"."COLORS_F$Delete" (
  "I_CLR_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_CLR_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  if I_CLR_ID IS NULL then
    raise exception 'Идентификатор цвета должен быть задан';
  end if;

  select count(*) into Counter
   from "SKLAD".Colors
  where clr_id = I_CLR_ID;
 
  if Counter = 0 then
    raise exception 'Указанной записи о цвете не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".STUFF
  where clr_id = I_CLR_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Данный цвет задан сырью';
  end if; 
  
  delete from "SKLAD".colors
  where clr_id = I_CLR_ID;
  
  return true;
 
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."COLORS_F$Insert" (
  "I_CLR_NAME" varchar,
  "I_CLR_CODE" varchar
)
RETURNS integer AS
$body$
DECLARE
  P_CLR_NAME "SKLAD".COLORS.CLR_NAME%TYPE;
  P_CLR_CODE "SKLAD".COLORS.CLR_CODE%TYPE;
  
  I_CLR_NAME ALIAS FOR $1;
  I_CLR_CODE ALIAS FOR $2;
  Counter INTEGER;
BEGIN
  P_CLR_NAME := TRIM(I_CLR_NAME);
  P_CLR_CODE := TRIM(I_CLR_CODE);
  
  if P_CLR_NAME IS NULL THEN
    raise exception 'Наименование цвета должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".colors
  where clr_name = P_CLR_NAME;
  
  if Counter > 0 then
    raise exception 'Такой цвет уже существует';
  end if;
  
  if P_CLR_CODE IS NULL THEN
    raise exception 'Код цвета должен быть задан';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".colors
  where clr_code = P_CLR_CODE;
  
  if Counter > 0 then
    raise exception 'Цвет с таким кодом уже существует';
  end if;
  
  insert into "SKLAD".colors
  values (nextval('"SKLAD".seq_colors'), P_CLR_NAME, P_CLR_CODE);
  
  Return currval('"SKLAD".seq_colors');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."COLORS_F$Update" (
  "I_CLR_ID" integer,
  "I_CLR_NAME" varchar,
  "I_CLR_CODE" varchar
)
RETURNS boolean AS
$body$
DECLARE
  P_CLR_NAME "SKLAD".COLORS.CLR_NAME%TYPE;
  P_CLR_CODE "SKLAD".COLORS.CLR_CODE%TYPE;
  
  I_CLR_ID ALIAS FOR $1;
  I_CLR_NAME ALIAS FOR $2;
  I_CLR_CODE ALIAS FOR $3;
  Counter INTEGER;
BEGIN
 P_CLR_NAME := TRIM(I_CLR_NAME);
 P_CLR_CODE := TRIM(I_CLR_CODE);
 
 if I_CLR_ID IS NULL then
   raise exception 'Идентификатор цвета должен быть задан';
 end if;
 
 select count(*) into Counter
  from "SKLAD".Colors
 where clr_id = I_CLR_ID;
 
 if Counter = 0 then
   raise exception 'Указанной записи о цвете не существует';
 end if;
  
  if P_CLR_NAME IS NULL THEN
    raise exception 'Наименование цвета должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".colors
  where clr_name = P_CLR_NAME
    and clr_id <> I_CLR_ID;
  
  if Counter > 0 then
    raise exception 'Такой цвет уже существует';
  end if;
  
  if P_CLR_CODE is null then
    raise exception 'Код цвета должен быть указан';
  end if;
  
  select count(*) into Counter
   from "SKLAD".COLORS
  where clr_code = I_CLR_CODE
    and clr_id <> I_CLR_ID;
    
  if Counter > 0 then
    raise exception 'Цвет с таким кодом уже существует';
  end if;
  
  update "SKLAD".colors SET
   clr_name = P_CLR_NAME,
   clr_code = P_CLR_CODE
  where clr_id = I_CLR_ID;  

  Return True;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."EXPENCES_F$Delete" (
  "I_EXP_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_EXP_ID ALIAS FOR $1;
  
  Counter INTEGER;
  l_sty_id "SKLAD".stuffyard.sty_id%TYPE;
  l_ord_id "SKLAD".orders.ord_id%TYPE;
  l_exp_volume "SKLAD".expences.exp_volume%TYPE;
  l_koef "SKLAD".stuff.stf_koef%TYPE;
BEGIN
  select count(*) into Counter
   from "SKLAD".expences
  where exp_id = I_EXP_ID;
  
  if Counter = 0 then
    raise exception 'Удаляемая запись о расходе не существует';
  end if;
  
  select sty_id, ord_id, exp_volume 
   into l_sty_id, l_ord_id, l_exp_volume
   from "SKLAD".expences e, 
        "SKLAD".rashodsklad r
  where e.exp_id = r.exp_id
    and e.exp_id = I_EXP_ID;
    
  begin
    select stf_koef into l_koef
     from "SKLAD".stuff
    where stf_id = (select stf_id 
                     from "SKLAD".stuffyard 
                    where sty_id = l_STY_ID);
  exception
    when others then
      l_koef := 0;
  end;    
    
  update "SKLAD".stuffyard set
    sty_square = (sty_square + l_exp_volume),
    sty_mass = (sty_square + l_exp_volume)*l_koef,
    sty_woff = False
  where sty_id = l_sty_id;
  
  delete from "SKLAD".rashodsklad 
  where exp_id = I_EXP_ID and sty_id = l_sty_id;
  
  delete from "SKLAD".expences where exp_id = I_EXP_ID;
/*  
  update "SKLAD".ordernomenclatures set
    exp_fact = (exp_fact - l_exp_volume)
  where ord_id = l_ord_id
    and nom_id = ;
*/  
  return True;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."EXPENCES_F$Insert" (
  "I_ORD_ID" integer,
  "I_STY_ID" integer,
  "I_EXP_DATE" date,
  "I_EXP_VOLUME" numeric
)
RETURNS integer AS
$body$
DECLARE
  I_ORD_ID ALIAS FOR $1;
  I_STY_ID ALIAS FOR $2;
  I_EXP_DATE ALIAS FOR $3;
  I_EXP_VOLUME ALIAS FOR $4;
  
  l_EXP_ID "SKLAD".expences.exp_id%TYPE;
  l_exp_volume "SKLAD".expences.exp_volume%TYPE;
  Counter INTEGER;
  l_sty_square "SKLAD".stuffyard.sty_square%TYPE;
  l_koef "SKLAD".stuff.stf_koef%TYPE;
BEGIN

  if I_ORD_ID IS NULL then
    raise exception 'Заказ не найден';
  end if;
  
  if I_STY_ID IS NULL then
    raise exception 'Сырье для списания со склада не выбрано';
  end if;
  
  if I_EXP_DATE IS NULL then
    raise exception 'Дата расхода должна быть указана';
  end if;
  
  if I_EXP_VOLUME IS NULL then
    raise exception 'Количество сырья для списания должно быть указано';
  end if;
  
  if I_EXP_VOLUME = 0 then
    raise exception 'Количество сырья для списания должно быть больше нуля';
  end if;  
  
  select sty_square into l_sty_square
   from "SKLAD".stuffyard
  where sty_id = I_STY_ID;
  
  if (I_EXP_VOLUME > l_sty_square) then
    raise exception 'Списываемое количество сырья не может быть больше его количества на складе';
  end if;
  
  begin
    select stf_koef into l_koef
     from "SKLAD".stuff
    where stf_id = (select stf_id 
                     from "SKLAD".stuffyard 
                    where sty_id = I_STY_ID);
  exception
    when others then
      l_koef := 0;
  end;
  
  if I_EXP_VOLUME = l_sty_square then
    update "SKLAD".stuffyard set
      sty_square = (sty_square - I_EXP_VOLUME),
      sty_mass = (sty_square - I_EXP_VOLUME)*l_koef,
      sty_woff = TRUE
    where sty_id = I_STY_ID;
  else
    update "SKLAD".stuffyard set
      sty_square = (sty_square - I_EXP_VOLUME),
      sty_mass = (sty_square - I_EXP_VOLUME)*l_koef
    where sty_id = I_STY_ID;    
  end if;
  
  insert into "SKLAD".expences
   values (nextval('"SKLAD".seq_expences'),I_ORD_ID,I_EXP_DATE,I_EXP_VOLUME);
    
  l_EXP_ID := currval('"SKLAD".seq_expences');
   
  insert into "SKLAD".rashodsklad
   values(l_EXP_ID,I_STY_ID);  
/*   
  update "SKLAD".orders set
    exp_fact = (exp_fact + I_EXP_VOLUME)
  where ord_id = I_ORD_ID;
*/   
  return l_exp_id;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."MAIN_F$CHANGEPASS" (
  "I_OLD_PASS" varchar,
  "I_NEW_PASS" varchar,
  "I_NEW_PASS_DBL" varchar
)
RETURNS boolean AS
$body$
DECLARE
  I_OLD_PASS ALIAS FOR $1;
  I_NEW_PASS ALIAS FOR $2;
  I_NEW_PASS_DBL ALIAS FOR $3;
  
  Counter INTEGER;
BEGIN
  if I_OLD_PASS IS NULL then
    raise exception 'Нужно ввести ваш текущий пароль';
  end if;
  
  select count(*) into Counter
   from pg_shadow
  where usename = current_user
    and passwd = 'md5'||md5(I_OLD_PASS||current_user);
    
  if Counter = 0 then
    raise exception 'Неверно введен текущий пароль';
  end if;

  if I_NEW_PASS IS NULL then
    raise exception 'Введите ваш новый пароль';
  end if;
  
  if I_NEW_PASS_DBL IS NULL then
    raise exception 'Введите повторно ваш новый пароль';
  end if;  
  
  if length(I_NEW_PASS) < 6 then
    raise exception 'Пароль должен быть длиной не менее 6 символов';
  end if;
  
  if (I_NEW_PASS <> I_NEW_PASS_DBL) then
    raise exception 'Пароли не совпадают';
  end if;  
  
  EXECUTE 'ALTER ROLE '||current_user||' PASSWORD '''||I_NEW_PASS||''' ';
  
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."NOMENCLATURES_F$Delete" (
  "I_NOM_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_NOM_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  if I_NOM_ID IS NULL then
    raise exception 'Номенклатура должна быть указана';
  end if;

  select count(*) into Counter
   from "SKLAD".NOMENCLATURES
  where nom_id = I_NOM_ID;
 
  if Counter = 0 then
    raise exception 'Удаляемой номенклатуры не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".ordernomenclatures
  where nom_id = I_NOM_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Номенклатура использована в заказе';
  end if; 
  
  select count(*) into Counter
   from "SKLAD".paramslibrarycust
  where nom_id = I_NOM_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. У номенклатуры есть список параметров';
  end if;
  
  delete from "SKLAD".NOMENCLATURES
  where nom_id = I_NOM_ID;
  
  return true;
 
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."NOMENCLATURES_F$Insert" (
  "I_NOM_NAME" varchar
)
RETURNS integer AS
$body$
DECLARE
  P_NOM_NAME "SKLAD".NOMENCLATURES.NOM_NAME%TYPE;
  libid "SKLAD".paramslibrary.lib_id%TYPE;
  junc INTEGER;
  
  I_NOM_NAME ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  P_NOM_NAME := TRIM(I_NOM_NAME);
  
  if P_NOM_NAME IS NULL THEN
    raise exception 'Наименование номенклатуры должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".NOMENCLATURES
  where nom_name = P_NOM_NAME;
  
  if Counter > 0 then
    raise exception 'Номенклатура с таким наименованием уже существует';
  end if;
  
  insert into "SKLAD".NOMENCLATURES (NOM_ID, NOM_NAME)
  values (nextval('"SKLAD".seq_nomenclatures'), P_NOM_NAME);

  -- Добавляем автоматически параметр Расход сырья
  select count(*) into Counter
   from "SKLAD".paramslibrary
  where UPPER(lib_name) = UPPER('Расход сырья');
  
  if Counter > 0 then
    select lib_id into libid
     from "SKLAD".paramslibrary
    where UPPER(lib_name) = UPPER('Расход сырья');
  else
    insert into "SKLAD".PARAMSLIBRARY (LIB_ID, LIB_NAME, LIB_TYPE)
     values (nextval('"SKLAD".seq_paramslibrary'), 'Расход сырья', 2);     
    libid := currval('"SKLAD".seq_paramslibrary');
  end if;
  
  if libid is not null then
    insert into "SKLAD".PARAMSLIBRARYCUST (PLC_ID, NOM_ID, LIB_ID, PLC_REQ)
     values (nextval('"SKLAD".seq_paramslibrarycust'), currval('"SKLAD".seq_nomenclatures'), libid, true);
   junc := currval('"SKLAD".seq_paramslibrarycust');
  else
    raise exception 'Параметр "Расход сырья" в библиотеке не определен';
  end if;
  
  -- Добавляем автоматически параметр "Цвет"
  select count(*) into Counter
   from "SKLAD".paramslibrary
  where UPPER(lib_name) = UPPER('Цвет');
  
  if Counter > 0 then
    select lib_id into libid
     from "SKLAD".paramslibrary
    where UPPER(lib_name) = UPPER('Цвет');
  else
    insert into "SKLAD".PARAMSLIBRARY (LIB_ID, LIB_NAME, LIB_TYPE)
     values (nextval('"SKLAD".seq_paramslibrary'), 'Цвет', 1);     
    libid := currval('"SKLAD".seq_paramslibrary');  
  end if;
  
  if libid is not null then
    insert into "SKLAD".PARAMSLIBRARYCUST (PLC_ID, NOM_ID, LIB_ID, PLC_REQ)
     values (nextval('"SKLAD".seq_paramslibrarycust'), currval('"SKLAD".seq_nomenclatures'), libid, true);
   junc := currval('"SKLAD".seq_paramslibrarycust');
  else
    raise exception 'Параметр "Цвет" в библиотеке не определен';
  end if;  
  
  Return currval('"SKLAD".seq_nomenclatures');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."NOMENCLATURES_F$Update" (
  "I_NOM_ID" integer,
  "I_NOM_NAME" varchar
)
RETURNS boolean AS
$body$
DECLARE
  P_NOM_NAME "SKLAD".NOMENCLATURES.NOM_NAME%TYPE;
  I_NOM_ID ALIAS FOR $1;
  I_NOM_NAME ALIAS FOR $2;
  Counter INTEGER;
BEGIN
 P_NOM_NAME := TRIM(I_NOM_NAME);
 
 if I_NOM_ID IS NULL then
   raise exception 'Номенклатура должна быть указана';
 end if;
 
 select count(*) into Counter
  from "SKLAD".NOMENCLATURES
 where nom_id = I_NOM_ID;
 
 if Counter = 0 then
   raise exception 'Изменяемой номенклатуры не существует';
 end if;
  
  if P_NOM_NAME IS NULL THEN
    raise exception 'Наименование номенклатуры должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".NOMENCLATURES
  where nom_name = P_NOM_NAME
    and nom_id <> I_NOM_ID;
  
  if Counter > 0 then
    raise exception 'Такая номенклатура уже существует';
  end if;
  
  update "SKLAD".NOMENCLATURES SET
   nom_name = P_NOM_NAME
  where nom_id = I_NOM_ID;  

  Return True;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."OBJECTS_F$Delete" (
  "I_OBJ_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_OBJ_ID ALIAS FOR $1;
  
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".Objects
  where obj_id = I_OBJ_ID;
  
  if Counter = 0 then 
    raise exception 'Удаляемой записи не существует';
  end if;

  select count(*) into Counter
   from "SKLAD".Orders
  where obj_id = I_OBJ_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Объект используется в заказе';
  end if;

  delete from "SKLAD".Objects where obj_id = I_OBJ_ID;

  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."OBJECTS_F$Delete" (
  "I_OBJ_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_OBJ_ID ALIAS FOR $1;
  
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".Objects
  where obj_id = I_OBJ_ID;
  
  if Counter = 0 then 
    raise exception 'Удаляемой записи не существует';
  end if;

  select count(*) into Counter
   from "SKLAD".Orders
  where obj_id = I_OBJ_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Объект используется в заказе';
  end if;

  delete from "SKLAD".Objects where obj_id = I_OBJ_ID;

  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."OBJECTS_F$Update" (
  "I_OBJ_ID" integer,
  "I_OBJ_NAME" varchar,
  "I_OBJ_ADDRESS" varchar,
  "I_USR_NAME" varchar,
  "I_OBJ_DATEFILL" varchar
)
RETURNS boolean AS
$body$
DECLARE
  I_OBJ_ID ALIAS FOR $1;
  I_OBJ_NAME ALIAS FOR $2;
  I_OBJ_ADDRESS ALIAS FOR $3;
  I_USR_NAME ALIAS FOR $4;

  P_OBJ_NAME "SKLAD".objects.obj_name%TYPE;
  P_OBJ_ADDRESS "SKLAD".objects.obj_address%TYPE;
  Counter INTEGER;	
BEGIN
  P_OBJ_NAME := TRIM(I_OBJ_NAME);
  P_OBJ_ADDRESS := TRIM(I_OBJ_ADDRESS);
  
  select count(*) into Counter
   from "SKLAD".Objects
  where obj_id = I_OBJ_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемой записи не существует';
  end if;
  
  if P_OBJ_NAME IS NULL then
    raise exception 'Наименование объекта должно быть указано';
  end if;
  
  if P_OBJ_ADDRESS IS NULL then
    raise exception 'Адрес объекта должен быть указан';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Objects 
  where obj_name = P_OBJ_NAME
    and obj_address = P_OBJ_ADDRESS
    and obj_id <> I_OBJ_ID;
    
  if Counter > 0 then
    raise exception 'Такой объект уже существует';
  end if;
  
  update "SKLAD".Objects set
    obj_name = P_OBJ_NAME,
    obj_address = P_OBJ_ADDRESS
  where obj_id = I_OBJ_ID;
  
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERNOMENCLATURES_F$Delete" (
  "I_ORD_ID" integer,
  "I_NOM_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_ORD_ID ALIAS FOR $1;
  I_NOM_ID ALIAS FOR $2;
  
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".ordernomenclatures
  where ord_id = I_ORD_ID
    and nom_id = I_NOM_ID;
    
  if Counter = 0 then
    raise exception 'Удаляемая номенклатура не найдена';
  end if;
  
  delete from "SKLAD".ordernomenclatures
   where ord_id = I_ORD_ID and nom_id = I_NOM_ID;
   
  delete from "SKLAD".orderparamsvalues
   where val_id in (select v.val_id 
                     from "SKLAD".valueparams v,
                          "SKLAD"."V$ALLPARAMS" p,
                          "SKLAD".orderparamsvalues pv
                    where p.plc_id = v.plc_id
                      and pv.val_id = v.val_id
                      and pv.ord_id = I_ORD_ID
                      and p.nom_id = I_NOM_ID);

  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERNOMENCLATURES_F$Insert" (
  "I_ORD_ID" integer,
  "I_NOM_ID" integer,
  "I_NOM_AMOUNT" numeric,
  "I_STF_ID" integer,
  "I_ORD_EXPPLAN" numeric,
  "I_ORD_EXPFACT" numeric
)
RETURNS boolean AS
$body$
DECLARE
  I_ORD_ID ALIAS FOR $1;
  I_NOM_ID ALIAS FOR $2;
  I_NOM_AMOUNT ALIAS FOR $3;
  I_STF_ID ALIAS FOR $4;
  I_ORD_EXPPLAN ALIAS FOR $5;
  I_ORD_EXPFACT ALIAS FOR $6;
  
  Counter INTEGER;
BEGIN
  if I_ORD_ID IS NULL then
    raise exception 'Заказ должен быть указан';
  end if;
  
  if I_NOM_ID IS NULL then
    raise exception 'Номенклатура должны быть указана';
  end if;

  select count(*) into Counter
   from "SKLAD".ordernomenclatures
  where ord_id = I_ORD_ID
    and nom_id = I_NOM_ID;
    
  if Counter > 0 then
    raise exception 'В текущем заказе уже присутствует указанная номенклатура';
  end if;
  
  if not (I_NOM_AMOUNT > 0) then
    raise exception 'Количество единиц номенклатуры должно быть больше нуля';
  end if;
  
  if I_STF_ID IS NULL then
    raise exception 'Cырье должно быть указано';
  end if;
    
  if I_ORD_EXPPLAN IS NULL then
    raise exception 'Плановый расход должен быть указан';  
  end if;  
  
  if not (I_ORD_EXPPLAN > 0) then
    raise exception 'Плановый расход должен быть больше нуля';  
  end if;  
  
  if I_ORD_EXPFACT IS NULL then
    raise exception 'Фактический расход должен быть указан';  
  end if;  
  
  if not (I_ORD_EXPFACT > 0) then
    raise exception 'Фактический расход должен быть больше нуля';  
  end if;   

  insert into "SKLAD".ordernomenclatures (ORD_ID, NOM_ID, NOM_AMOUNT,
  										  STF_ID, EXP_PLAN, EXP_FACT)
   values (I_ORD_ID, I_NOM_ID, I_NOM_AMOUNT,
           I_STF_ID, I_ORD_EXPPLAN, I_ORD_EXPFACT);
   
   return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERNOMENCLATURES_F$Update" (
  "I_ORD_ID" integer,
  "I_NOM_ID" integer,
  "I_NOM_AMOUNT" numeric,
  "I_STF_ID" integer,
  "I_ORD_EXPPLAN" numeric,
  "I_ORD_EXPFACT" numeric
)
RETURNS boolean AS
$body$
DECLARE
  I_ORD_ID ALIAS FOR $1;
  I_NOM_ID ALIAS FOR $2;
  I_NOM_AMOUNT ALIAS FOR $3;
  I_STF_ID ALIAS FOR $4;
  I_ORD_EXPPLAN ALIAS FOR $5;
  I_ORD_EXPFACT ALIAS FOR $6;
  
  Counter INTEGER;
BEGIN
if I_ORD_ID IS NULL then
    raise exception 'Заказ должен быть указан';
  end if;
  
  if I_NOM_ID IS NULL then
    raise exception 'Номенклатура должны быть указана';
  end if;

  if not (I_NOM_AMOUNT > 0) then
    raise exception 'Количество единиц номенклатуры должно быть больше нуля';
  end if;
  
  if I_STF_ID IS NULL then
    raise exception 'Cырье должно быть указано';
  end if;
    
  if I_ORD_EXPPLAN IS NULL then
    raise exception 'Плановый расход должен быть указан';  
  end if;  
  
  if not (I_ORD_EXPPLAN > 0) then
    raise exception 'Плановый расход должен быть больше нуля';  
  end if;  
  
  if I_ORD_EXPFACT IS NULL then
    raise exception 'Фактический расход должен быть указан';  
  end if;  
  
  if not (I_ORD_EXPFACT > 0) then
    raise exception 'Фактический расход должен быть больше нуля';  
  end if;   

  update "SKLAD".ordernomenclatures SET
    NOM_AMOUNT = I_NOM_AMOUNT,
    STF_ID = I_STF_ID,
    EXP_PLAN = I_ORD_EXPPLAN,
    EXP_FACT = I_ORD_EXPFACT
  where ORD_ID = I_ORD_ID and NOM_ID = I_NOM_ID;
   
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERPARAMSVALUES_F$Delete" (
  "I_ORD_ID" integer,
  "I_VAL_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_ORD_ID ALIAS FOR $1;
  I_VAL_ID ALIAS FOR $2;
  
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".orderparamsvalues
  where ord_id = I_ORD_ID
    and val_id = I_VAL_ID;
    
  if Counter = 0 then
    raise exception 'Удаляемого значения параметра не существует';
  end if;
  
  delete from "SKLAD".orderparamsvalues
  where ord_id = I_ORD_ID
    and val_id = I_VAL_ID;
  
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERPARAMSVALUES_F$Insert" (
  "I_ORD_ID" integer,
  "I_VAL_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_ORD_ID ALIAS FOR $1;
  I_VAL_ID ALIAS FOR $2;
  
  Counter INTEGER;
BEGIN
  if I_ORD_ID IS NULL then
    raise exception 'Заказ должен быть указан';
  end if;
  
  if I_VAL_ID IS NULL then
    raise exception 'Значение параметра должно быть указано';
  end if;
  
  select count(*) into Counter
   from "SKLAD".orderparamsvalues
  where ord_id = I_ORD_ID and val_id = I_VAL_ID;
  
  if Counter > 0 then 
    raise exception 'Для данного заказа уже использовано выбранное значение параметра';
  end if;
  
  insert into "SKLAD".orderparamsvalues (ORD_ID, VAL_ID)
   values (I_ORD_ID, I_VAL_ID);
   
  return true; 
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERS_F$Delete" (
  "I_ORD_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_ORD_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".Orders
  where ord_id = I_ORD_ID;
  
  if Counter = 0 then
    raise exception 'Удаляемого заказа не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Expences
  where ord_id = I_ORD_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. По этому заказу существует расход';
  end if;

  select count(*) into Counter
   from "SKLAD".ordernomenclatures
  where ord_id = I_ORD_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно пока в заказ добавлены номенклатуры';
  end if;
  
  delete from "SKLAD".orderparamsvalues where ord_id = I_ORD_ID;

  delete from "SKLAD".Orders where ord_id = I_ORD_ID;
    
  Return true;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERS_F$Insert" (
  "I_OBJ_ID" integer,
  "I_ORD_NUMBER" varchar,
  "I_ORD_DATEFILL" date,
  "I_ORD_DATECOMPLETE" date
)
RETURNS integer AS
$body$
DECLARE
  P_ORD_NUMBER "SKLAD".ORDERS.ORD_NUMBER%TYPE;
  I_OBJ_ID ALIAS FOR $1;
  I_ORD_NUMBER ALIAS FOR $2;
  I_ORD_DATEFILL ALIAS FOR $3;
  I_ORD_DATECOMPLETE ALIAS FOR $4;

  I_USR_ID "SKLAD".Users.USR_ID%TYPE;
  Counter INTEGER;
BEGIN
  P_ORD_NUMBER := TRIM(I_ORD_NUMBER);
  
  if (P_ORD_NUMBER IS NULL) OR (length(P_ORD_NUMBER)=0) THEN
    raise exception 'Номер заказа должен быть указан';
  END IF;
  
  if I_OBJ_ID IS NULL then
    raise exception 'Объект должен быть указан';
  end if;
  
  if I_ORD_DATEFILL IS NULL then
    raise exception 'Дата оформления заказа должна быть указана';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Users
  where usesysid = (select usesysid from pg_user where usename = current_user);
  
  if Counter > 0 then
    select usr_id into I_USR_ID
     from "SKLAD".Users
    where usesysid = (select usesysid from pg_user where usename = current_user); 
  else
    I_USR_ID := null;
  end if;
  
  select count(*) into Counter
   from "SKLAD".Orders
  where ord_number = P_ORD_NUMBER
    and date_part('year',ord_datefill)::varchar(4) = date_trunc('year',I_ORD_DATEFILL)::varchar(4);
  
  if Counter > 0 then
    raise exception 'Заказ с таким номером в текущем году уже существует';
  end if;
  
  insert into "SKLAD".Orders (ORD_ID, OBJ_ID, ORD_NUMBER, ORD_DATEFILL,
  							  ORD_DATECOMPLETE, USR_ID)
  values (nextval('"SKLAD".seq_orders'), 
          I_OBJ_ID, P_ORD_NUMBER, I_ORD_DATEFILL, 
          I_ORD_DATECOMPLETE, I_USR_ID);
  
  Return currval('"SKLAD".seq_orders');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERS_F$Update" (
  "I_ORD_ID" integer,
  "I_OBJ_ID" integer,
  "I_ORD_NUMBER" varchar,
  "I_ORD_DATEFILL" date,
  "I_ORD_DATECOMPLETE" date
)
RETURNS boolean AS
$body$
DECLARE
  P_ORD_NUMBER "SKLAD".ORDERS.ORD_NUMBER%TYPE;
  I_ORD_ID ALIAS FOR $1;
  I_OBJ_ID ALIAS FOR $2;
  I_ORD_NUMBER ALIAS FOR $3;
  I_ORD_DATEFILL ALIAS FOR $4;
  I_ORD_DATECOMPLETE ALIAS FOR $5;

  Counter INTEGER;
BEGIN
  P_ORD_NUMBER := TRIM(I_ORD_NUMBER);
  
  select count(*) into Counter
   from "SKLAD".Orders
  where ord_id = I_ORD_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемого заказа не существует';
  end if;
  
  if (P_ORD_NUMBER IS NULL) OR (length(P_ORD_NUMBER)=0) THEN
    raise exception 'Номер заказа должен быть указан';
  END IF;
  
  if I_OBJ_ID IS NULL then
    raise exception 'Объект должен быть указан';
  end if;
  
  if I_ORD_DATEFILL IS NULL then
    raise exception 'Дата оформления заказа должна быть указана';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Orders
  where ord_number = P_ORD_NUMBER
    and date_part('year',ord_datefill)::varchar(4) = date_trunc('year',I_ORD_DATEFILL)::varchar(4)
    and ord_id <> I_ORD_ID;
  
  if Counter > 0 then
    raise exception 'Заказ с таким номером в текущем году уже существует';
  end if;
  
  update "SKLAD".Orders set
    obj_id = I_OBJ_ID,
    ord_number = I_ORD_NUMBER,
    ord_datefill = I_ORD_DATEFILL,
    ord_datecomplete = I_ORD_DATECOMPLETE
  where ord_id = I_ORD_ID;
    
  Return true;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."ORDERS_F$Update" (
  "I_ORD_ID" integer,
  "I_OBJ_ID" integer,
  "I_ORD_NUMBER" varchar,
  "I_ORD_DATEFILL" date,
  "I_ORD_DATECOMPLETE" date
)
RETURNS boolean AS
$body$
DECLARE
  P_ORD_NUMBER "SKLAD".ORDERS.ORD_NUMBER%TYPE;
  I_ORD_ID ALIAS FOR $1;
  I_OBJ_ID ALIAS FOR $2;
  I_ORD_NUMBER ALIAS FOR $3;
  I_ORD_DATEFILL ALIAS FOR $4;
  I_ORD_DATECOMPLETE ALIAS FOR $5;

  Counter INTEGER;
BEGIN
  P_ORD_NUMBER := TRIM(I_ORD_NUMBER);
  
  select count(*) into Counter
   from "SKLAD".Orders
  where ord_id = I_ORD_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемого заказа не существует';
  end if;
  
  if (P_ORD_NUMBER IS NULL) OR (length(P_ORD_NUMBER)=0) THEN
    raise exception 'Номер заказа должен быть указан';
  END IF;
  
  if I_OBJ_ID IS NULL then
    raise exception 'Объект должен быть указан';
  end if;
  
  if I_ORD_DATEFILL IS NULL then
    raise exception 'Дата оформления заказа должна быть указана';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Orders
  where ord_number = P_ORD_NUMBER
    and date_part('year',ord_datefill)::varchar(4) = date_trunc('year',I_ORD_DATEFILL)::varchar(4)
    and ord_id <> I_ORD_ID;
  
  if Counter > 0 then
    raise exception 'Заказ с таким номером в текущем году уже существует';
  end if;
  
  update "SKLAD".Orders set
    obj_id = I_OBJ_ID,
    ord_number = I_ORD_NUMBER,
    ord_datefill = I_ORD_DATEFILL,
    ord_datecomplete = I_ORD_DATECOMPLETE
  where ord_id = I_ORD_ID;
    
  Return true;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PARAMSLIBRARYCUST_F$Insert" (
  "I_LIB_ID" integer,
  "I_NOM_ID" integer,
  "I_PLC_REQ" boolean
)
RETURNS integer AS
$body$
DECLARE
  I_LIB_ID ALIAS FOR $1;
  I_NOM_ID ALIAS FOR $2;
  I_PLC_REQ ALIAS FOR $3;
  Counter INTEGER;
BEGIN
 
  if I_LIB_ID IS NULL then
    raise exception 'Параметр должен быть указан';
  end if;
  
  if I_NOM_ID IS NULL then
    raise exception 'Номенклатура должна быть указана';
  end if;
  
  if I_PLC_REQ IS NULL then
    raise exception 'Укажите обязателен ли параметр';
  end if;
  
  select count(*) into Counter
   from "SKLAD".PARAMSLIBRARYCUST
  where lib_id = I_LIB_ID
    and nom_id = I_NOM_ID;
  
  if Counter > 0 then
    raise exception 'Этот параметр для указаной номенклатуры уже существует';
  end if;
  
  insert into "SKLAD".PARAMSLIBRARYCUST (PLC_ID, NOM_ID, LIB_ID, PLC_REQ)
  values (nextval('"SKLAD".seq_paramslibrarycust'), I_NOM_ID, I_LIB_ID, I_PLC_REQ);
  
  Return currval('"SKLAD".seq_paramslibrarycust');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PARAMSLIBRARYCUST_F$SETMANDATORY" (
  "I_PLC_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_PLC_ID ALIAS FOR $1;
  
  Checked BOOLEAN;
  Counter INTEGER;
  l_PLC_REQ "SKLAD".PARAMSLIBRARYCUST.PLC_REQ%TYPE;
BEGIN
  Checked := false;
  begin
    select plc_req into l_plc_req 
     from "SKLAD".paramslibrarycust where plc_id = I_PLC_ID;
  exception
   WHEN NO_DATA_FOUND then
     raise exception 'Параметр не найден.';
  end;
  
  select count(*) into Counter
   from "SKLAD".paramslibrarycust p,
        "SKLAD".paramslibrary l
  where p.lib_id = l.lib_id
    and p.plc_id = I_PLC_ID
    and ((UPPER(l.lib_name) = UPPER('Расход сырья')) or
         (UPPER(l.lib_name) = UPPER('Цвет')));
         
  if Counter > 0 then
    raise exception 'Указаный параметр номенклатуры не может быть изменен';
  end if;

  if (l_plc_req is null) or (l_plc_req = '0') then
    Checked := true;
  else
    Checked := false;
  end if;

  if Checked then
   update "SKLAD".paramslibrarycust set
     plc_req = '1'
   where plc_id = I_PLC_ID;
  else
   update "SKLAD".paramslibrarycust set
     plc_req = '0'
   where plc_id = I_PLC_ID;
  end if;

  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PARAMSLIBRARYCUST_F$Update" (
  "I_PLC_ID" integer,
  "I_LIB_ID" integer,
  "I_NOM_ID" integer,
  "I_PLC_REQ" boolean
)
RETURNS boolean AS
$body$
DECLARE
  I_PLC_ID ALIAS FOR $1;
  I_LIB_ID ALIAS FOR $2;
  I_NOM_ID ALIAS FOR $3;
  I_PLC_REQ ALIAS FOR $4;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".PARAMSLIBRARYCUST
  where plc_id = I_PLC_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемого параметра не существует';
  end if;
  
  if I_LIB_ID IS NULL then
    raise exception 'Параметр должен быть указан';
  end if;
  
  if I_NOM_ID IS NULL then
    raise exception 'Номенклатура должна быть указана';
  end if;
  
  if I_PLC_REQ IS NULL then
    raise exception 'Укажите обязателен ли параметр';
  end if;
  
  select count(*) into Counter
   from "SKLAD".PARAMSLIBRARYCUST
  where lib_id = I_LIB_ID
    and nom_id = I_NOM_ID
    and plc_id <> I_PLC_ID;
  
  if Counter > 0 then
    raise exception 'Этот параметр для указаной номенклатуры уже существует';
  end if;
  
  update "SKLAD".PARAMSLIBRARYCUST set
    nom_id = I_NOM_ID, 
    lib_id = I_LIB_ID, 
    plc_req = I_PLC_REQ
  where plc_id = I_PLC_ID;
  
  Return true;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PARAMSLIBRARY_F$Delete" (
  "I_LIB_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_LIB_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  if I_LIB_ID IS NULL then
    raise exception 'Идентификатор параметра должен быть задан';
  end if;

  select count(*) into Counter
   from "SKLAD".PARAMSLIBRARY
  where lib_id = I_LIB_ID;
 
  if Counter = 0 then
    raise exception 'Удаляемой записи о параметре не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".PARAMSLIBRARYCUST
  where lib_id = I_LIB_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Существует номенклатура с данным параметром';
  end if; 
  
  delete from "SKLAD".PARAMSLIBRARY
  where lib_id = I_LIB_ID;
  
  return true;
 
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PARAMSLIBRARY_F$Insert" (
  "I_LIB_NAME" varchar,
  "I_LIB_TYPE" varchar
)
RETURNS integer AS
$body$
DECLARE
  P_LIB_NAME "SKLAD".PARAMSLIBRARY.LIB_NAME%TYPE;
  I_LIB_NAME ALIAS FOR $1;
  I_LIB_TYPE ALIAS FOR $2;
  Counter INTEGER;
BEGIN
  P_LIB_NAME := TRIM(I_LIB_NAME);
  
  if P_LIB_NAME IS NULL THEN
    raise exception 'Наименование параметра должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".PARAMSLIBRARY
  where lib_name = P_LIB_NAME;
  
  if Counter > 0 then
    raise exception 'Параметр с таким наименованием уже существует';
  end if;
  
  if not ((I_LIB_TYPE = '1') or (I_LIB_TYPE = '2') or (I_LIB_TYPE = '3')) then
    raise exception 'Неверно задан тип параметра';
  end if;
  
  insert into "SKLAD".PARAMSLIBRARY (LIB_ID, LIB_NAME, LIB_TYPE)
  values (nextval('"SKLAD".seq_paramslibrary'), P_LIB_NAME, I_LIB_TYPE);
  
  Return currval('"SKLAD".seq_paramslibrary');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PARAMSLIBRARY_F$Update" (
  "I_LIB_ID" integer,
  "I_LIB_NAME" varchar,
  "I_LIB_TYPE" varchar
)
RETURNS boolean AS
$body$
DECLARE
  P_LIB_NAME "SKLAD".PARAMSLIBRARY.LIB_NAME%TYPE;
  I_LIB_ID ALIAS FOR $1;
  I_LIB_NAME ALIAS FOR $2;
  I_LIB_TYPE ALIAS FOR $3;
  Counter INTEGER;
BEGIN
 P_LIB_NAME := TRIM(I_LIB_NAME);
 
 if I_LIB_ID IS NULL then
   raise exception 'Идентификатор типа сырья должен быть задан';
 end if;
 
 select count(*) into Counter
  from "SKLAD".PARAMSLIBRARY
 where lib_id = I_LIB_ID;
 
 if Counter = 0 then
   raise exception 'Изменяемой записи о типе сырья не существует';
 end if;
  
  if P_LIB_NAME IS NULL THEN
    raise exception 'Наименование типа сырья должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".PARAMSLIBRARY
  where lib_name = P_LIB_NAME
    and lib_id <> I_LIB_ID;
  
  if Counter > 0 then
    raise exception 'Такой тип сырья уже существует';
  end if;
  
  if not ((I_LIB_TYPE = '1') or (I_LIB_TYPE = '2') or (I_LIB_TYPE = '3')) then
    raise exception 'Неверно задан тип параметра';
  end if;
  
  update "SKLAD".PARAMSLIBRARY SET
   lib_name = P_LIB_NAME,
   lib_type = I_LIB_TYPE
  where lib_id = I_LIB_ID;  

  Return True;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PRODUCERS_F$Delete" (
  "I_PRC_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_PRC_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  if I_PRC_ID IS NULL then
    raise exception 'Идентификатор производителя должен быть задан';
  end if;

  select count(*) into Counter
   from "SKLAD".Producers
  where prc_id = I_PRC_ID;
 
  if Counter = 0 then
    raise exception 'Указанной записи о производителе не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".stuff
  where prc_id = I_PRC_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Данный производитель указан для сырья';
  end if;
  
  delete from "SKLAD".Producers
  where prc_id = I_PRC_ID;
  
  return true;
 
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PRODUCERS_F$Insert" (
  "I_PRC_NAME" varchar
)
RETURNS integer AS
$body$
DECLARE
  P_PRC_NAME "SKLAD".PRODUCERS.PRC_NAME%TYPE;
  I_PRC_NAME ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  P_PRC_NAME := TRIM(I_PRC_NAME);
  
  if P_PRC_NAME IS NULL THEN
    raise exception 'Наименование производителя должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".producers
  where prc_name = P_PRC_NAME;
  
  if Counter > 0 then
    raise exception 'Такой производитель уже существует';
  end if;
  
  insert into "SKLAD".producers (PRC_ID, PRC_NAME)
  values (nextval('"SKLAD".seq_producers'), P_PRC_NAME);
  
  Return currval('"SKLAD".seq_producers');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."PRODUCERS_F$Update" (
  "I_PRC_ID" integer,
  "I_PRC_NAME" varchar
)
RETURNS boolean AS
$body$
DECLARE
  P_PRC_NAME "SKLAD".PRODUCERS.PRC_NAME%TYPE;
  I_PRC_ID ALIAS FOR $1;
  I_PRC_NAME ALIAS FOR $2;
  Counter INTEGER;
BEGIN
 P_PRC_NAME := TRIM(I_PRC_NAME);
 
 if I_PRC_ID IS NULL then
   raise exception 'Идентификатор производителя должен быть задан';
 end if;
 
 select count(*) into Counter
  from "SKLAD".Producers
 where prc_id = I_PRC_ID;
 
 if Counter = 0 then
   raise exception 'Изменяемой записи о производителе не существует';
 end if;
  
  if P_PRC_NAME IS NULL THEN
    raise exception 'Наименование производителя должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".Producers
  where prc_name = P_PRC_NAME
    and prc_id <> I_PRC_ID;
  
  if Counter > 0 then
    raise exception 'Такой производитель уже существует';
  end if;
  
  update "SKLAD".Producers SET
   prc_name = P_PRC_NAME
  where prc_id = I_PRC_ID;  

  Return True;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFFTYPE_F$Delete" (
  "I_STT_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_STT_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  if I_STT_ID IS NULL then
    raise exception 'Идентификатор типа сырья должен быть задан';
  end if;

  select count(*) into Counter
   from "SKLAD".Stufftype
  where stt_id = I_STT_ID;
 
  if Counter = 0 then
    raise exception 'Указанной записи о типе сырья не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Stuff
  where stt_id = I_STT_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Существует сырье с данным типом';
  end if; 
  
  delete from "SKLAD".Stufftype
  where stt_id = I_STT_ID;
  
  return true;
 
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFFTYPE_F$Insert" (
  "I_STT_NAME" varchar
)
RETURNS integer AS
$body$
DECLARE
  P_STT_NAME "SKLAD".STUFFTYPE.STT_NAME%TYPE;
  I_STT_NAME ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  P_STT_NAME := TRIM(I_STT_NAME);
  
  if P_STT_NAME IS NULL THEN
    raise exception 'Наименование типа сырья должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".stufftype
  where stt_name = P_STT_NAME;
  
  if Counter > 0 then
    raise exception 'Такой тип сырья уже существует';
  end if;
  
  insert into "SKLAD".stufftype (STT_ID, STT_NAME)
  values (nextval('"SKLAD".seq_stufftypes'), P_STT_NAME);
  
  Return currval('"SKLAD".seq_stufftypes');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFFTYPE_F$Update" (
  "I_STT_ID" integer,
  "I_STT_NAME" varchar
)
RETURNS boolean AS
$body$
DECLARE
  P_STT_NAME "SKLAD".STUFFTYPE.STT_NAME%TYPE;
  I_STT_ID ALIAS FOR $1;
  I_STT_NAME ALIAS FOR $2;
  Counter INTEGER;
BEGIN
 P_STT_NAME := TRIM(I_STT_NAME);
 
 if I_STT_ID IS NULL then
   raise exception 'Идентификатор типа сырья должен быть задан';
 end if;
 
 select count(*) into Counter
  from "SKLAD".Stufftype
 where stt_id = I_STT_ID;
 
 if Counter = 0 then
   raise exception 'Изменяемой записи о типе сырья не существует';
 end if;
  
  if P_STT_NAME IS NULL THEN
    raise exception 'Наименование типа сырья должно быть задано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".Stufftype
  where stt_name = P_STT_NAME
    and stt_id <> I_STT_ID;
  
  if Counter > 0 then
    raise exception 'Такой тип сырья уже существует';
  end if;
  
  update "SKLAD".Stufftype SET
   stt_name = P_STT_NAME
  where stt_id = I_STT_ID;  

  Return True;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFFYARD_F$Delete" (
  "I_STY_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_STY_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".STUFFYARD
  where sty_id = I_STY_ID;
  
  if Counter = 0 then
    raise exception 'Удаляемой записи о сырье на складе не существует';
  end if;
   
  select count(*) into Counter
   from "SKLAD".RASHODSKLAD
  where sty_id = I_STY_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Данное сырье списано в расход';
  end if;
  
  delete from "SKLAD".STUFFYARD where sty_id = I_STY_ID;
  
  return true;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFFYARD_F$Insert" (
  "I_STF_ID" integer,
  "I_STY_SQUARE" numeric,
  "I_STY_MASS" numeric,
  "I_STY_DATE" date
)
RETURNS integer AS
$body$
DECLARE
  I_STF_ID ALIAS FOR $1;
  I_STY_SQUARE ALIAS FOR $2;
  I_STY_MASS ALIAS FOR $3;
  I_STY_DATE ALIAS FOR $4;
  
  I_STY_WOFF BOOLEAN;
  Counter INTEGER;
BEGIN
  I_STY_WOFF := False;
  
  if I_STF_ID IS NULL then
    raise exception 'Сырье должно быть указано';
  end if;
   
  if I_STY_SQUARE IS NULL then
    raise exception 'Площадь должна быть указана';
  end if;
  
  if not (I_STY_SQUARE > 0) then
    raise exception 'Площадь должна быть больше нуля';
  end if;
  
  if I_STY_MASS IS NULL then
    raise exception 'Масса сырья должна быть указана';
  end if;
  
  if not (I_STY_MASS > 0) then
    raise exception 'Масса должна быть больше нуля';
  end if;  
  
  if I_STY_DATE IS NULL then
    raise exception 'Дата поступления должна быть указана';
  end if;
  
  insert into "SKLAD".STUFFYARD (STY_ID, STF_ID, STY_SQUARE, STY_MASS, STY_DATE, STY_WOFF)
  values (nextval('"SKLAD".seq_stuffyard'),I_STF_ID,I_STY_SQUARE,I_STY_MASS,I_STY_DATE,I_STY_WOFF);
  
  return currval('"SKLAD".seq_stuffyard');
  
  commit;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFFYARD_F$Update" (
  "I_STY_ID" integer,
  "I_STF_ID" integer,
  "I_STY_SQUARE" numeric,
  "I_STY_MASS" numeric,
  "I_STY_DATE" date
)
RETURNS boolean AS
$body$
DECLARE
  I_STY_ID ALIAS FOR $1;
  I_STF_ID ALIAS FOR $2;
  I_STY_SQUARE ALIAS FOR $3;
  I_STY_MASS ALIAS FOR $4;
  I_STY_DATE ALIAS FOR $5;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".STUFFYARD
  where sty_id = I_STY_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемой записи о сырье на складе не существует';
  end if;
   
  if I_STF_ID IS NULL then
    raise exception 'Сырье должно быть указано';
  end if;
  
  if I_STY_SQUARE IS NULL then
    raise exception 'Площадь должна быть указана';
  end if;
  
  if not (I_STY_SQUARE > 0) then
    raise exception 'Площадь должна быть больше нуля';
  end if;
  
  if I_STY_MASS IS NULL then
    raise exception 'Масса сырья должна быть указана';
  end if;
  
  if not (I_STY_MASS > 0) then
    raise exception 'Масса должна быть больше нуля';
  end if;    
  
  if I_STY_DATE IS NULL then
    raise exception 'Дата поступления должна быть указана';
  end if;
  
  update "SKLAD".STUFFYARD set
    stf_id = I_STF_ID,
    sty_square = I_STY_SQUARE,
    sty_mass = I_STY_MASS,
    sty_date = I_STY_DATE
  where sty_id = I_STY_ID;
  
  return true;
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFF_F$Delete" (
  "I_STF_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_STF_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".STUFF
  where stf_id = I_STF_ID;
  
  if Counter = 0 then
    raise exception 'Удаляемого сырья не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".STUFFYARD
  where STF_ID = I_STF_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Сырье присутствует на складе';
  end if; 

  select count(*) into Counter
   from "SKLAD".ordernomenclatures
  where STF_ID = I_STF_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Даннное сырье указано в заказе';
  end if; 
  
  delete from "SKLAD".stuff where stf_id = I_STF_ID;
  
  Return true;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFF_F$Insert" (
  "I_STF_DESC" varchar,
  "I_STF_THICK" numeric,
  "I_STF_KOEF" numeric,
  "I_CLR_ID" integer,
  "I_STT_ID" integer,
  "I_PRC_ID" integer
)
RETURNS integer AS
$body$
DECLARE
  P_STF_DESC "SKLAD".STUFF.STF_DESC%TYPE;
  I_STF_DESC ALIAS FOR $1;
  I_STF_THICK ALIAS FOR $2;
  I_STF_KOEF ALIAS FOR $3;
  I_CLR_ID ALIAS FOR $4;
  I_STT_ID ALIAS FOR $5;
  I_PRC_ID ALIAS FOR $6;
  Counter INTEGER;
BEGIN
  P_STF_DESC := TRIM(I_STF_DESC);
  
  if I_STF_THICK IS NULL then
    raise exception 'Толщина должна быть указана';
  end if;
  
  if I_STF_KOEF IS NULL then
    raise exception 'Коеффициент пересчета расхода сырья в кв.м.';
  end if;
  
  if I_CLR_ID IS NULL then
    raise exception 'Цвет сырья должен быть указан';
  end if;
  
  if I_STT_ID IS NULL then
    raise exception 'Тип сырья должен быть указан';
  end if;
  
  if I_PRC_ID IS NULL then
    raise exception 'Производитель должен быть указан';
  end if;
  
  select count(*) into Counter
   from "SKLAD".STUFF
  where STT_ID = I_STT_ID
    and stf_thick = I_STF_THICK;
  
  if Counter > 0 then
    raise exception 'Сырье указанного типа и толщины уже существует';
  end if;
  
  insert into "SKLAD".stuff (STF_ID, CLR_ID, STT_ID, PRC_ID,
  							 STF_DESC, STF_THICK, STF_KOEF)
  values (nextval('"SKLAD".seq_stuffs'), 
          I_CLR_ID, I_STT_ID, I_PRC_ID,
          I_STF_DESC, I_STF_THICK, I_STF_KOEF);
  
  Return currval('"SKLAD".seq_stuffs');
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."STUFF_F$Update" (
  "I_STF_ID" integer,
  "I_STF_DESC" varchar,
  "I_STF_THICK" numeric,
  "I_STF_KOEF" numeric,
  "I_CLR_ID" integer,
  "I_STT_ID" integer,
  "I_PRC_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  P_STF_DESC "SKLAD".STUFF.STF_DESC%TYPE;

  I_STF_ID ALIAS FOR $1;
  I_STF_DESC ALIAS FOR $2;
  I_STF_THICK ALIAS FOR $3;
  I_STF_KOEF ALIAS FOR $4;
  I_CLR_ID ALIAS FOR $5;
  I_STT_ID ALIAS FOR $6;
  I_PRC_ID ALIAS FOR $7;
  
  Counter INTEGER;
BEGIN
  P_STF_DESC := TRIM(I_STF_DESC);
  
  select count(*) into Counter
   from "SKLAD".STUFF
  where stf_id = I_STF_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемого сырья не существует';
  end if;
  
  if I_STF_THICK IS NULL then
    raise exception 'Толщина должна быть указана';
  end if;
  
  if I_STF_KOEF IS NULL then
    raise exception 'Коеффициент пересчета расхода сырья в кв.м.';
  end if;
  
  if I_CLR_ID IS NULL then
    raise exception 'Цвет сырья должен быть указан';
  end if;
  
  if I_STT_ID IS NULL then
    raise exception 'Тип сырья должен быть указан';
  end if;
  
  if I_PRC_ID IS NULL then
    raise exception 'Производитель должен быть указан';
  end if;
  
  select count(*) into Counter
   from "SKLAD".STUFF
  where stt_id = I_STT_ID
    and stf_thick = I_STF_THICK
    and stf_id <> I_STF_ID;
  
  if Counter > 0 then
    raise exception 'Сырье указанного типа и толщины уже существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".STUFF s, "SKLAD".STUFFYARD y
  where s.stf_id = I_STF_ID 
    and s.stf_koef <> I_STF_KOEF
    and s.stf_id = y.stf_id;
    
  if Counter > 0 then
    raise exception 'Запрещено менять значение коэффициента для сырья, присутствующего на складе';
  end if;
  
  update "SKLAD".stuff set
    clr_id = I_CLR_ID, 
    stt_id = I_STT_ID, 
    prc_id = I_PRC_ID,
    stf_desc = P_STF_DESC, 
    stf_thick = I_STF_THICK, 
    stf_koef = I_STF_KOEF
  where stf_id = I_STF_ID;
  
  Return true;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."SYSUSERS_F$Delete" (
  "I_USESYSID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_USESYSID ALIAS FOR $1;
  
  l_USESYSNAME VARCHAR;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from pg_user
  where usesysid = I_USESYSID;
  
  if Counter = 0 then
    raise exception 'Удаляемого пользователя не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".USERS
  where USESYSID = I_USESYSID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Логин связан с существующим пользователем';
  end if;
  
  select usename into l_USESYSNAME
   from pg_user
  where usesysid = I_USESYSID;
  
  EXECUTE 'DROP USER '||l_USESYSNAME;
  
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."SYSUSERS_F$Delete" (
  "I_USESYSID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_USESYSID ALIAS FOR $1;
  
  l_USESYSNAME VARCHAR;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from pg_user
  where usesysid = I_USESYSID;
  
  if Counter = 0 then
    raise exception 'Удаляемого пользователя не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".USERS
  where USESYSID = I_USESYSID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Логин связан с существующим пользователем';
  end if;
  
  select usename into l_USESYSNAME
   from pg_user
  where usesysid = I_USESYSID;
  
  EXECUTE 'DROP USER '||l_USESYSNAME;
  
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."USERS_F$Delete" (
  "I_USR_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_USR_ID ALIAS FOR $1;
  
  l_ROLEID INTEGER;
  l_ROLENAME VARCHAR;
  l_USESYSNAME VARCHAR;
  Counter INTEGER;
BEGIN
  select count(*) into Counter
   from "SKLAD".Users
  where USR_ID = I_USR_ID;
  
  if Counter = 0 then
    raise exception 'Удаляемого пользователя не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Orders
  where usr_id = I_USR_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Существуют заказы, внесенные этим пользователем';
  end if;
  
  select count(*) into Counter
   from "SKLAD".objects
  where usr_id = I_USR_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Существуют объекты, внесенные этим пользователем';
  end if;  
  
  select u.usename, s.roleid  
   into l_USESYSNAME, l_ROLEID
   from "SKLAD".users s, pg_user u
  where s.USR_ID = I_USR_ID
    and s.usesysid = u.usesysid;
  
  if l_USESYSNAME IS NULL then
    raise exception 'Системный пользователь не найден';
  end if;
  
  if l_ROLEID IS NOT NULL then
    select rolname into l_ROLENAME
     from pg_roles
    where oid = l_ROLEID;
    
    EXECUTE 'REVOKE '||l_ROLENAME||' FROM '||l_USESYSNAME;
  end if;
  
  delete from "SKLAD".Users where USR_ID = I_USR_ID;
    
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."USERS_F$Insert" (
  "I_USR_NAME" varchar,
  "I_USESYSID" integer,
  "I_ROLEID" integer
)
RETURNS integer AS
$body$
DECLARE
  P_USR_NAME "SKLAD".USERS.USR_NAME%TYPE;
  l_USESYSNAME VARCHAR;
  l_ROLE_NAME VARCHAR;
  Counter INTEGER;
  
  I_USR_NAME ALIAS FOR $1;
  I_USESYSID ALIAS FOR $2;
  I_ROLEID ALIAS FOR $3;  
BEGIN
  P_USR_NAME := TRIM(I_USR_NAME);
  
  if P_USR_NAME IS NULL THEN
    raise exception 'Имя пользователя должно быть указано';
  END IF;
  
  select count(*) into Counter
   from "SKLAD".Users
  where USR_NAME = P_USR_NAME;
  
  if Counter > 0 then
    raise exception 'Пользователь с таким именем уже существует';
  end if;
  
  if I_USESYSID IS NULL then
    raise exception 'Системный пользователь БД должен быть указан';
  end if;

  select count(*) into Counter
   from "SKLAD".users
  where usesysid = I_USESYSID;
  
  if Counter > 0 then
    raise exception 'Пользователь с таким логином уже существует';
  end if;
  
  select usename into l_USESYSNAME
   from pg_user
  where usesysid = I_USESYSID;
  
  begin
   if I_ROLEID IS NOT NULL then
     select rolname into l_ROLE_NAME
      from pg_roles
     where oid = I_ROLEID;
    
     EXECUTE 'GRANT '||l_ROLE_NAME||' TO '||l_USESYSNAME;
   end if;
  exception
    when no_data_found then
      raise exception 'Выбранной роли доступа для пользователя не существует';
    when others then
      I_ROLEID := null;
  end;
  
  insert into "SKLAD".Users (USR_ID, USR_NAME, USESYSID, ROLEID)
  values (nextval('"SKLAD".seq_users'), P_USR_NAME, I_USESYSID, I_ROLEID);
  
  Return currval('"SKLAD".seq_users');
  
  commit;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."USERS_F$Update" (
  "I_USR_ID" integer,
  "I_USR_NAME" varchar,
  "I_USESYSID" integer,
  "I_ROLEID" integer
)
RETURNS boolean AS
$body$
DECLARE
  l_USESYSNAME VARCHAR;
  l_USESYSNAME_new VARCHAR;
  l_ROLENAME VARCHAR;
  l_ROLENAME_new VARCHAR;
  P_USR_NAME "SKLAD".USERS.USR_NAME%TYPE;
  Counter INTEGER;

  I_USR_ID ALIAS FOR $1;
  I_USR_NAME ALIAS FOR $2;
  I_USESYSID ALIAS FOR $3;
  I_ROLEID ALIAS FOR $4;
BEGIN
  P_USR_NAME := TRIM(I_USR_NAME);

  select count(*) into Counter
   from "SKLAD".Users
  where USR_ID = I_USR_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемого пользователя не существует';
  end if;
  
  if P_USR_NAME IS NULL THEN
    raise exception 'Имя пользователя должно быть указано';
  end if;
  
  select count(*) into Counter
   from "SKLAD".Users
  where USR_NAME = P_USR_NAME
    and USR_ID <> I_USR_ID;
  
  if Counter > 0 then
    raise exception 'Пользователь с таким именем уже существует';
  end if;  
  
  if I_USESYSID IS NULL then
    raise exception 'Системное имя пользователя БД (логин) должно быть указано';
  end if; 
  
  select count(*) into Counter
   from pg_user
  where usesysid = I_USESYSID;
  
  if Counter = 0 then
    raise exception 'Системный пользователь с таким именем не существует';
  end if; 
  
  select count(*) into Counter
   from pg_user p, "SKLAD".Users u
  where p.usesysid = u.USESYSID
    and p.usesysid = I_USESYSID
    and u.USR_ID <> I_USR_ID;
    
  if Counter > 0 then
    raise exception 'Этот системный пользователь уже связан с другим аккаунтом';
  end if;  
  
  select usename into l_USESYSNAME_new
   from pg_user
  where usesysid = I_USESYSID;
  
  select usename into l_USESYSNAME
   from "SKLAD".USERS u, pg_user r
  where u.usesysid = r.usesysid
    and u.usr_id = I_USR_ID;
  
  begin
    select rolname into l_ROLENAME
     from pg_roles
    where oid = (select roleid 
    			  from "SKLAD".Users 
                 where usr_id = I_USR_ID);
  exception
    when no_data_found then
      l_ROLENAME := null;
  end;
  
  begin
    select rolname into l_ROLENAME_new
     from pg_roles
    where oid = I_ROLEID;
  exception
    when no_data_found then
      l_ROLENAME_new := null;
  end;
  
  if l_USESYSNAME = l_USESYSNAME_new then  
    if not (I_ROLEID > 0) then
      if l_ROLENAME IS NULL then
        -- nothing
      else
        -- revoke role
        EXECUTE 'REVOKE '||l_ROLENAME||' from '||l_USESYSNAME;
      end if;
    else
      if l_ROLENAME IS NULL THEN
        -- grant new role
        EXECUTE 'GRANT '||l_ROLENAME_new||' to '||l_USESYSNAME;
      else
        if l_ROLENAME = l_ROLENAME_new then
        --   nothing
        else
        --   revoke old role
          EXECUTE 'REVOKE '||l_ROLENAME||' from '||l_USESYSNAME;
        --   grant new role
          EXECUTE 'GRANT '||l_ROLENAME_new||' to '||l_USESYSNAME;
        end if;
      end if;
    end if;
  else -- Если пользователь был изменен
    if not (I_ROLEID > 0) then
      if l_ROLENAME IS NULL then
        -- nothing
      else
        -- revoke role from old user
        EXECUTE 'REVOKE '||l_ROLENAME||' from '||l_USESYSNAME;
      end if;
    else
      if l_ROLENAME IS NULL THEN
        -- grant new role to new user
        EXECUTE 'GRANT '||l_ROLENAME_new||' to '||l_USESYSNAME_new;
      else
        --   revoke old role from old user
        EXECUTE 'REVOKE '||l_ROLENAME||' from '||l_USESYSNAME;
        --   grant new role to new user
        EXECUTE 'GRANT '||l_ROLENAME_new||' to '||l_USESYSNAME_new;
      end if;
    end if;  
  end if;

  update "SKLAD".USERS set
   USR_NAME = P_USR_NAME,
   USESYSID = I_USESYSID,
   ROLEID = I_ROLEID
  where USR_ID = I_USR_ID;
  
  return true;
EXCEPTION
WHEN others THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."VALUEPARAMS_F$Delete" (
  "I_VAL_ID" integer
)
RETURNS boolean AS
$body$
DECLARE
  I_VAL_ID ALIAS FOR $1;
  Counter INTEGER;
BEGIN
  
  select count(*) into Counter
   from "SKLAD".VALUEPARAMS
  where val_id = I_VAL_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемого значения параметра не существует';
  end if;
  
  select count(*) into Counter
   from "SKLAD".orderparamsvalues
  where val_id = I_VAL_ID;
  
  if Counter > 0 then
    raise exception 'Удаление невозможно. Значение параметра уже применено к номенклатуре в заказе.';
  end if;
  
  delete from "SKLAD".VALUEPARAMS where VAL_ID = I_VAL_ID;
  
  Return True;
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."VALUEPARAMS_F$Insert" (
  "I_PLC_ID" integer,
  "I_VAL_VARCHAR" varchar,
  "I_VAL_NUM" numeric,
  "I_VAL_DATE" date
)
RETURNS integer AS
$body$
DECLARE
  P_VAL_VARCHAR "SKLAD".VALUEPARAMS.VAL_VARCHAR%TYPE;
  I_PLC_ID ALIAS FOR $1;
  I_VAL_VARCHAR ALIAS FOR $2;
  I_VAL_NUM ALIAS FOR $3;
  I_VAL_DATE ALIAS FOR $4;
  
  Counter INTEGER;
  libtype INTEGER;
BEGIN
  P_VAL_VARCHAR := TRIM(I_VAL_VARCHAR);
  
  if I_PLC_ID is NULL then
    raise exception 'Параметр должен быть указан';
  end if;
  
  if (P_VAL_VARCHAR IS NULL) AND (I_VAL_NUM IS NULL) AND (I_VAL_DATE IS NULL) then
    raise exception 'Укажите значение одного из параметров';
  end if;  
  
  if ((P_VAL_VARCHAR IS NOT NULL) AND (I_VAL_NUM IS NOT NULL)) OR 
     ((I_VAL_NUM IS NOT NULL) AND (I_VAL_DATE IS NOT NULL)) OR
     ((P_VAL_VARCHAR IS NOT NULL) AND (I_VAL_DATE IS NOT NULL)) 
  then
    raise exception 'Должно быть задано только одно значение параметра';
  end if;    
  
  select lib_type::integer into libtype
   from "SKLAD"."V$ALLPARAMS"
  where plc_id = I_PLC_ID;
  
  if (libtype = 1) and ((P_VAL_VARCHAR IS NULL)) then
    raise exception 'Параметр может иметь только строковое значение';
  end if;
  
  if (libtype = 2) then
    if (I_VAL_NUM IS NULL) then
      raise exception 'Параметр может иметь только числовое значение';
    else
      if not (I_VAL_NUM > 0) then
        raise exception 'Значение параметра должно быть больше нуля';
      end if;
    end if;
  end if;
  
  if (libtype = 3) and (I_VAL_DATE IS NULL) then
    raise exception 'Параметр может быть может иметь значение только даты';
  end if;    
  
  select COUNT(*) into Counter
   from "SKLAD".VALUEPARAMS
    where plc_id = I_PLC_ID
      and val_varchar = P_VAL_VARCHAR
      and val_num = I_VAL_NUM
      and val_date = I_VAL_DATE;

    if Counter > 0 then
      raise exception 'Такое значение параметра уже существует';
    end if;

  insert into "SKLAD".VALUEPARAMS (VAL_ID, PLC_ID, VAL_VARCHAR,
  								   VAL_NUM, VAL_DATE)
  values (nextval('"SKLAD".seq_valueparams'), 
          I_PLC_ID,
          P_VAL_VARCHAR,
          I_VAL_NUM,
          I_VAL_DATE);
  
  Return currval('"SKLAD".seq_valueparams');
  
  commit;
EXCEPTION
  when others then
   raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;

CREATE OR REPLACE FUNCTION "SKLAD"."VALUEPARAMS_F$Update" (
  "I_VAL_ID" integer,
  "I_PLC_ID" integer,
  "I_VAL_VARCHAR" varchar,
  "I_VAL_NUM" numeric,
  "I_VAL_DATE" date
)
RETURNS boolean AS
$body$
DECLARE
  P_VAL_VARCHAR "SKLAD".VALUEPARAMS.VAL_VARCHAR%TYPE;
  I_VAL_ID ALIAS FOR $1;
  I_PLC_ID ALIAS FOR $2;
  I_VAL_VARCHAR ALIAS FOR $3;
  I_VAL_NUM ALIAS FOR $4;
  I_VAL_DATE ALIAS FOR $5;
  
  Counter INTEGER;
  libtype INTEGER;
BEGIN
  P_VAL_VARCHAR := TRIM(I_VAL_VARCHAR);
  
  select count(*) into Counter
   from "SKLAD".VALUEPARAMS
  where val_id = I_VAL_ID;
  
  if Counter = 0 then
    raise exception 'Изменяемого значения параметра не существует';
  end if;
  
  if I_PLC_ID is NULL then
    raise exception 'Параметр должен быть указан';
  end if;

  if (P_VAL_VARCHAR IS NULL) AND (I_VAL_NUM IS NULL) AND (I_VAL_DATE IS NULL) then
    raise exception 'Укажите значение одного из параметров';
  end if;  
  
/*  
  select COUNT(*) into Counter
   from "SKLAD".VALUEPARAMS
    where plc_id = I_PLC_ID
      and ord_id = I_ORD_ID
      and val_id <> I_VAL_ID;

    if Counter > 0 then
      raise exception 'Комбинация параметра номенклатуры и заказа должны быть уникальной';
    end if;
*/
  if ((P_VAL_VARCHAR IS NOT NULL) AND (I_VAL_NUM IS NOT NULL)) OR 
     ((I_VAL_NUM IS NOT NULL) AND (I_VAL_DATE IS NOT NULL)) OR
     ((P_VAL_VARCHAR IS NOT NULL) AND (I_VAL_DATE IS NOT NULL)) 
  then
    raise exception 'Должно быть задано только одно значение параметра';
  end if;    
  
  select lib_type::integer into libtype
   from "SKLAD"."V$ALLPARAMS"
  where plc_id = I_PLC_ID;
  
  if (libtype = 1) and ((P_VAL_VARCHAR IS NULL)) then
    raise exception 'Параметр может иметь только строковое значение';
  end if;
  
  if (libtype = 2) then
    if (I_VAL_NUM IS NULL) then
      raise exception 'Параметр может иметь только числовое значение';
    else
      if not (I_VAL_NUM > 0) then
        raise exception 'Значение параметра должно быть больше нуля';
      end if;
    end if;
  end if;
  
  if (libtype = 3) and (I_VAL_DATE IS NULL) then
    raise exception 'Параметр может быть может иметь значение только даты';
  end if;    
  
  select COUNT(*) into Counter
   from "SKLAD".VALUEPARAMS
    where plc_id = I_PLC_ID
      and val_varchar = P_VAL_VARCHAR
      and val_num = I_VAL_NUM
      and val_date = I_VAL_DATE
      and val_id <> I_VAL_ID;

    if Counter > 0 then
      raise exception 'Такое значение параметра уже существует';
    end if;
      
  update "SKLAD".VALUEPARAMS set
    plc_id = I_PLC_ID,
    val_varchar = P_VAL_VARCHAR,
    val_num = I_VAL_NUM,
    val_date = I_VAL_DATE
  where val_id = I_VAL_ID;
  
  Return True;
  
  commit;
  
EXCEPTION
WHEN OTHERS THEN
  raise;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;